// Test for the util::regexp interface
// Copyright 2004 (C) Ralph Thomas

#include <util/regexp.h>
#include <tests/testCore.h>
#include <util/log.h>

namespace util {
	//
	/// This test exercises the regexp::match method. Note that this is
	/// NOT meant to be testing the underlying regexp implementation,
	/// it is merely testing that the wrapper around the regexp
	/// implementation.
	//
	class testRegexpMatch : public test::basic {
	  public:
		const char* performTest() {
			util::string expr = "^abc(\\d+)def(\\d+)";
			util::string matching = "abc1234def5678";
			util::string nmatching = "hello cruel world";

			regexp* r = regexp::fromString( expr );
			if( !r ) return "regexp couldn't be created from valid pattern";

			if( !r->match( matching ) ) return "regexp did not match matching data";
			if( r->match( nmatching ) ) return "regexp matched non matching data";
			delete r;
			return NULL;
		}

		const char* getTestName() {
			return "Test matching ability of util::regexp";
		}
	};

	//
	/// test that side effects get executed as required, and that all parts
	/// of the matched string can be accessed as expected.
	//
	class testRegexpSideEffects : public test::basic {
	  private:
		class pro : public regexp::stringProcessor {
		  private:
			bool _worked;
		  public:
			pro() : _worked( false ) {}
			virtual ~pro() {}

			util::string getPattern() { return "b12b(\\d+)dff"; }
			util::string getData() { return "b12b65536dff"; }
			bool getWorked() { return _worked; }
			virtual void processString( const regexp::matchedString* str ) {
				if( !str ) return;
				if( str->getMatchedItem( 0 ) != getData() ) return;
				if( str->getMatchedItem( 1 ) != "65536" ) return;
				if( str->getMatchedItem( 2 ) != "" ) return;
				_worked = true;
			}

		};
	  public:
		virtual const char* performTest() {
			pro* p = new pro();
			regexp* r = regexp::fromStringAndProcessor( p->getPattern(), p );
			if( !r ) return "could not create regexp";
			if( !r->match( p->getData() ) ) return "data did not match pattern";
			if( !p->getWorked() ) return "test failed processing side effects";
			delete r;
			return NULL;
		}

		virtual const char* getTestName() {
			return "Testing side-effects of regexp";
		}
	};
};

void test::runnerSingleton::registerTests() {
	adoptTest( new util::testRegexpMatch() );
	adoptTest( new util::testRegexpSideEffects() );
}

